package com.sakura.java8.lambda;

import com.sakura.java8.lambda.pojo.Employee;
import com.sakura.java8.lambda.service.MyPredicate;
import com.sakura.java8.lambda.service.impl.FilterEmployeeForAge;
import com.sakura.java8.lambda.service.impl.FilterEmployeeForSalary;
import org.junit.Test;

import java.util.*;

/**
 * @Author Sakura
 * @Date 2022/11/7 11:36
 * @Version 1.0
 */
public class SimpleLambda {


    /**
     * 原来写法
     * 匿名内部类比较两个Integer得大小
     */
    @Test
    public void testOldCompare() {
        Comparator<Integer> com = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };

        TreeSet<Integer> ts=new TreeSet<>(com);
        //TODO 为了使用 Integer.compare(o1, o2); 而不得不写匿名类

    }

    /**
     * 现在写法
     */
    @Test
    public void testNewCompate() {
        Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
        TreeSet<Integer> ts = new TreeSet<>(com);
    }


    List<Employee> emps = Arrays.asList(
            new Employee(101, "张三", 18, 9999.99),
            new Employee(102, "李四", 59, 6666.66),
            new Employee(103, "王五", 28, 3333.33),
            new Employee(104, "赵六", 8, 7777.77),
            new Employee(105, "田七", 38, 5555.55)
    );
    /**
     *  获取公司中年龄小于 35 的员工信息
     */
    @Test
    public void test01(){
        List<Employee> list = new ArrayList<>();

        for (Employee emp : emps) {
            if(emp.getAge() <= 35){
                list.add(emp);
            }
        }

        for (Employee employee : list) {
            System.out.println(employee);
        }
    }

    /**
     * 获取公司中工资大于 5000 的员工信息
     */
    @Test
    public void test02(){
        List<Employee> list = new ArrayList<>();

        for (Employee emp : emps) {
            if(emp.getSalary() >= 5000){
                list.add(emp);
            }
        }

        for (Employee employee : list) {
            System.out.println(employee);
        }
    }

    /**
     * 优化方式一
     * 优化上面两种需求(设计模式)
     * 策略设计模式
     * 但是每次有新功能需要新增一个类
     */
    @Test
    public void test03(){
        FilterEmployeeForAge filterEmployeeForAge = new FilterEmployeeForAge();
        List<Employee> list = new ArrayList<>();
        for (Employee employee : emps) {
            if(filterEmployeeForAge.test(employee)){
                list.add(employee);
            }
        }
        for (Employee employee : list) {
            System.out.println(employee);
        }

        System.out.println("------------------------------------------");

        FilterEmployeeForSalary filterEmployeeForSalary = new FilterEmployeeForSalary();
        list.clear();
        for (Employee employee : emps) {
            if(filterEmployeeForSalary.test(employee)){
                list.add(employee);
            }
        }
        for (Employee employee : list) {
            System.out.println(employee);
        }

    }

    /**
     * 优化方式二
     * 匿名内部类
     * 无需新增类
     */
    @Test
    public void test04(){
        List<Employee> list = filterEmployee(emps, new MyPredicate<Employee>() {
            @Override
            public boolean test(Employee t) {
                return t.getId() <= 103;
            }
        });

        for (Employee employee : list) {
            System.out.println(employee);
        }
    }

    public List<Employee> filterEmployee(List<Employee> emps, MyPredicate<Employee> mp){
        List<Employee> list = new ArrayList<>();
        for (Employee employee : emps) {
            if(mp.test(employee)){
                list.add(employee);
            }
        }
        return list;
    }

    /**
     * 使用 Lambda
     */
    @Test
    public void test05() {
        List<Employee> employees = filterEmployee(emps, (e) -> e.getSalary() >= 5000);
        employees.forEach(System.out::println);
    }

    //优化方式四：Stream API
    @Test
    public void test6(){
        emps.stream()
                .filter((e) -> e.getAge() <= 35)
                .forEach(System.out::println);

        System.out.println("----------------------------------------------");

        emps.stream()
                .map(Employee::getName)
                .limit(3)
                .sorted()
                .forEach(System.out::println);
    }
}
